<template>
	<view class="container">
		<button @tap="openBluetoothAdapter">开始扫描</button>
		<button @tap="stopBluetoothDevicesDiscovery">停止扫描</button>
		<button @tap="closeBluetoothAdapter">结束流程</button>

		<view class="devices_summary">已发现 {{devices.length}} 个外围设备：</view>
		<scroll-view class="device_list" scroll-y scroll-with-animation>
			<view v-for="(item, index) in devices" :key="index" :data-device-id="item.deviceId"
				:data-name="item.name || item.localName" @tap="createBLEConnection" class="device_item"
				hover-class="device_item_hover">
				<view style="font-size: 16px; color: #333;">{{item.name || item.localName || '未知设备'}}</view>
				<view style="font-size: 10px">信号强度: {{item.RSSI}}dBm ({{calculateSignalPercentage(item.RSSI)}}%)</view>
				<view style="font-size: 10px">UUID: {{item.deviceId}}</view>
				<view style="font-size: 10px">Service数量: {{calculateServiceCount(item.advertisServiceUUIDs)}}</view>
			</view>
		</scroll-view>

		<view class="connected_info" v-if="connected">
			<view>
				<text>已连接到 {{name}}</text>
				<view class="operation">
					<button v-if="canWrite" size="mini" @tap="writeBLECharacteristicValue">写数据</button>
					<button size="mini" @tap="closeBLEConnection">断开连接</button>
				</view>
			</view>

			<view class="blood-pressure-data" v-if="bloodPressureData">
				<view class="section-title">身高体重测量结果</view>
				<view>身高: {{bloodPressureData.systolic}} mmHg</view>
				<view>体重: {{bloodPressureData.diastolic}} mmHg</view>
				<view>BMI: {{bloodPressureData.pulse}} 次/分</view>
				<!-- <view v-if="bloodPressureData.measurementTime">测量时间: {{formatTime(bloodPressureData.measurementTime)}}
				</view>
				<view v-if="bloodPressureData.checksumValid !== undefined">校验结果:
					{{bloodPressureData.checksumValid ? '有效' : '无效'}}</view>
				<view v-if="bloodPressureData.dataFormat">数据格式: {{bloodPressureData.dataFormat}}</view> -->
			</view>

			<view v-for="(item, index) in chs" :key="index" style="font-size: 12px; margin-top: 10px;">
				<view>特性UUID: {{item.uuid}}</view>
				<view>特性值: {{item.value}}</view>
			</view>
		</view>
	</view>
</template>

<script>
	// 工具函数定义
	const utils = {
		max: function(n1, n2) {
			return Math.max(n1, n2)
		},
		len: function(arr) {
			arr = arr || []
			return arr.length
		}
	}

	function inArray(arr, key, val) {
		if (!arr || !Array.isArray(arr)) return -1;
		for (let i = 0; i < arr.length; i++) {
			if (arr[i][key] === val) {
				return i;
			}
		}
		return -1;
	}

	// ArrayBuffer转16进度字符串示例
	function ab2hex(buffer) {
		if (!buffer) return '';
		try {
			var hexArr = Array.prototype.map.call(
				new Uint8Array(buffer),
				function(bit) {
					return ('00' + bit.toString(16)).slice(-2)
				}
			)
			return hexArr.join('');
		} catch (e) {
			console.error('ab2hex error:', e)
			return '';
		}
	}

	export default {
		data() {
			return {
				devices: [],
				connected: false,
				chs: [],
				canWrite: false,
				name: '',
				deviceId: '',
				_deviceId: '',
				_serviceId: '',
				_characteristicId: '',
				_discoveryStarted: false,
				bloodPressureData: null // 新增：血压数据
			}
		},
		methods: {
			// 计算信号强度百分比
			calculateSignalPercentage(rssi) {
				return utils.max(0, (rssi || 0) + 100);
			},
			// 计算服务数量
			calculateServiceCount(services) {
				return utils.len(services);
			},
			// 格式化时间显示
			formatTime(date) {
				if (!date) return '未知时间';
				return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
			},
			openBluetoothAdapter() {
				uni.showLoading({
					title: '初始化蓝牙...'
				});

				uni.openBluetoothAdapter({
					success: (res) => {
						console.log('openBluetoothAdapter success', res)
						uni.hideLoading();
						this.startBluetoothDevicesDiscovery()
					},
					fail: (res) => {
						console.log('openBluetoothAdapter fail', res)
						uni.hideLoading();
						uni.showModal({
							title: '提示',
							content: '请打开手机蓝牙功能',
							showCancel: false
						});
					}
				})
			},
			getBluetoothAdapterState() {
				uni.getBluetoothAdapterState({
					success: (res) => {
						console.log('getBluetoothAdapterState', res)
						if (res.discovering) {
							this.onBluetoothDeviceFound()
						} else if (res.available) {
							this.startBluetoothDevicesDiscovery()
						}
					}
				})
			},
			startBluetoothDevicesDiscovery() {
				if (this._discoveryStarted) {
					return
				}
				this._discoveryStarted = true

				uni.showLoading({
					title: '扫描中...'
				});

				uni.startBluetoothDevicesDiscovery({
					allowDuplicatesKey: true,
					success: (res) => {
						console.log('startBluetoothDevicesDiscovery success', res)
						uni.hideLoading();
						this.onBluetoothDeviceFound()
					},
					fail: (res) => {
						console.log('startBluetoothDevicesDiscovery fail', res)
						uni.hideLoading();
						this._discoveryStarted = false;
						uni.showToast({
							title: '扫描失败',
							icon: 'none'
						});
					}
				})
			},
			stopBluetoothDevicesDiscovery() {
				uni.stopBluetoothDevicesDiscovery();
				this._discoveryStarted = false;
				uni.showToast({
					title: '已停止扫描',
					icon: 'success'
				});
			},
			onBluetoothDeviceFound() {
				uni.onBluetoothDeviceFound((res) => {
					if (res.devices && res.devices.length > 0) {
						res.devices.forEach(device => {
							if (!device.name && !device.localName) {
								return
							}
							const idx = inArray(this.devices, 'deviceId', device.deviceId)
							if (idx === -1) {
								this.devices.push(device)
							} else {
								this.$set(this.devices, idx, device)
							}
						})
					}
				})
			},
			createBLEConnection(e) {
				const deviceId = e.currentTarget.dataset.deviceId;
				const name = e.currentTarget.dataset.name;

				uni.showLoading({
					title: '连接中...'
				});

				uni.createBLEConnection({
					deviceId,
					success: (res) => {
						uni.hideLoading();
						this.connected = true
						this.name = name
						this.deviceId = deviceId
						this.getBLEDeviceServices(deviceId)
					},
					fail: (res) => {
						uni.hideLoading();
						console.log('createBLEConnection fail', res)
						uni.showToast({
							title: '连接失败',
							icon: 'none'
						})
					}
				})
				this.stopBluetoothDevicesDiscovery()
			},
			closeBLEConnection() {
				if (this.deviceId) {
					uni.closeBLEConnection({
						deviceId: this.deviceId
					})
				}
				this.connected = false
				this.chs = []
				this.canWrite = false
				this.name = ''
				this.deviceId = ''
				this.bloodPressureData = null // 清除血压数据

				uni.showToast({
					title: '已断开连接',
					icon: 'success'
				});
			},
			getBLEDeviceServices(deviceId) {
				console.log("开始获取设备服务...")
				uni.getBLEDeviceServices({
					deviceId,
					success: (res) => {
						console.log('getBLEDeviceServices success', res.services)
						if (res.services && res.services.length > 0) {
							// 查找主服务
							let primaryService = null;
							for (let i = 0; i < res.services.length; i++) {
								if (res.services[i].isPrimary) {
									primaryService = res.services[i];
									break;
								}
							}
							// 如果没有主服务，使用第一个服务
							if (!primaryService && res.services.length > 0) {
								primaryService = res.services[0];
							}

							if (primaryService) {
								this.getBLEDeviceCharacteristics(deviceId, primaryService.uuid)
							}
						} else {
							console.log('未找到服务')
							uni.showToast({
								title: '未找到服务',
								icon: 'none'
							})
						}
					},
					fail: (res) => {
						console.log('getBLEDeviceServices fail', res)
						uni.showToast({
							title: '获取服务失败',
							icon: 'none'
						})
					}
				})
			},
			getBLEDeviceCharacteristics(deviceId, serviceId) {
				// 先设置监听
				this.setupBLECharacteristicValueChangeListener();

				// 然后获取特征值
				uni.getBLEDeviceCharacteristics({
					deviceId,
					serviceId,
					success: (res) => {
						console.log('getBLEDeviceCharacteristics success', res.characteristics)
						if (res.characteristics && res.characteristics.length > 0) {
							for (let i = 0; i < res.characteristics.length; i++) {
								let item = res.characteristics[i]
								if (item.properties.read) {
									uni.readBLECharacteristicValue({
										deviceId,
										serviceId,
										characteristicId: item.uuid,
									})
								}
								if (item.properties.write) {
									this.canWrite = true
									this._deviceId = deviceId
									this._serviceId = serviceId
									this._characteristicId = item.uuid
								}
								if (item.properties.notify || item.properties.indicate) {
									uni.notifyBLECharacteristicValueChange({
										deviceId,
										serviceId,
										characteristicId: item.uuid,
										state: true,
									})
								}
							}
						}
					},
					fail: (res) => {
						console.error('getBLEDeviceCharacteristics', res)
					}
				})
			},
			setupBLECharacteristicValueChangeListener() {
				uni.onBLECharacteristicValueChange((characteristic) => {
					console.log("onBLECharacteristicValueChange", characteristic);

					if (characteristic.value && characteristic.value instanceof ArrayBuffer) {
						const dataArray = new Uint8Array(characteristic.value);

						console.log("数据长度:", dataArray.length);
						console.log("原始字节:", Array.from(dataArray));
						console.log("16进制:", ab2hex(characteristic.value));
					}

					const idx = inArray(this.chs, 'uuid', characteristic.characteristicId)
					const newValue = {
						uuid: characteristic.characteristicId,
						value: ab2hex(characteristic.value)
					}

					if (idx === -1) {
						this.chs.push(newValue)
					} else {
						this.$set(this.chs, idx, newValue)
					}
				})
			},
			closeBluetoothAdapter() {
				uni.closeBluetoothAdapter()
				this._discoveryStarted = false
				this.devices = []
				this.connected = false
				this.chs = []
				this.canWrite = false
				this.bloodPressureData = null

				uni.showToast({
					title: '蓝牙已关闭',
					icon: 'success'
				});
			},
		},
		onUnload() {
			// 页面卸载时关闭蓝牙适配器
			this.closeBluetoothAdapter()
		}
	}
</script>

<style>
	.container {
		padding: 20rpx;
		color: #333;
	}

	button {
		margin: 10rpx 0;
	}

	.devices_summary {
		margin-top: 30rpx;
		padding: 20rpx;
		font-size: 32rpx;
	}

	.device_list {
		height: 600rpx;
		margin: 20rpx 0;
		border: 1px solid #EEE;
		border-radius: 10rpx;
	}

	.device_item {
		border-bottom: 1px solid #EEE;
		padding: 20rpx;
		color: #666;
	}

	.device_item_hover {
		background-color: rgba(0, 0, 0, .1);
	}

	.connected_info {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		background-color: #F0F0F0;
		padding: 20rpx;
		padding-bottom: 40rpx;
		font-size: 28rpx;
		min-height: 200rpx;
		box-shadow: 0px -2rpx 10rpx rgba(0, 0, 0, 0.1);
	}

	.connected_info .operation {
		position: absolute;
		right: 30rpx;
		top: 20rpx;
	}

	.connected_info .operation button {
		margin-left: 10rpx;
	}

	.blood-pressure-data {
		margin-top: 20rpx;
		padding: 20rpx;
		background-color: #fff;
		border-radius: 10rpx;
		border: 1px solid #ddd;
	}

	.section-title {
		font-size: 32rpx;
		font-weight: bold;
		margin-bottom: 15rpx;
		color: #007AFF;
	}
</style>